package mongodb.jdbc;

import com.mongodb.DB;
import java.sql.Array;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Properties;
import java.util.ResourceBundle;
import mongodb.conn.ServerConnection;
import unity.annotation.GlobalSchema;
import unity.engine.Attribute;
import unity.engine.IServerConnection;
import unity.generic.jdbc.ConnectionImpl;
import unity.jdbc.UnityDriver;

public class MongoConnection extends ConnectionImpl
{
    protected static ResourceBundle resources = ResourceBundle.getBundle("resources/mongo/MongoConnection", locale);

    public MongoConnection(String url, ArrayList<String> servers, ArrayList<Integer> ports, String dbname, Properties info, String mongoURI)
            throws SQLException
    {
        this.url = url;
        this.clientInfo = info;
        if (this.clientInfo == null)
        {
            this.clientInfo = new Properties();
        }

        String tempDBname = dbname;

        if (this.clientInfo.containsKey("dbname"))
        {
            tempDBname = this.clientInfo.getProperty("dbname");
        }
        UnityDriver.debug("Database to connect to URL:  " + url);
        for (int i = 0; i < servers.size(); i++) {
            UnityDriver.debug("  Server:  " + (String)servers.get(i) + ":" + ports.get(i));
        }
        this.connection = new ServerConnection(servers, ports, tempDBname, this.url, this, mongoURI);
        this.clientInfo.put("dbname", tempDBname);
        this.connection.connect(this.clientInfo);
    }

    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
            throws SQLException
    {
        if (resultSetType == 1005)
        {
            throw new SQLException(resources.getString("nosupportScrollSensitive"));
        }

        return new MongoStatement(this, this.connection, resultSetType, resultSetConcurrency);
    }

    public DatabaseMetaData getMetaData()
            throws SQLException
    {
        return new MongoDatabaseMetaData(this, this.connection);
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
            throws SQLException
    {
        return new MongoPreparedStatement(this, this.connection, resultSetType, resultSetConcurrency, sql);
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
            throws SQLException
    {
        return new MongoPreparedStatement(this, this.connection, resultSetType, resultSetConcurrency, sql);
    }

    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
            throws SQLException
    {
        return new MongoPreparedStatement(this, this.connection, 1003, 1007, sql);
    }

    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
            throws SQLException
    {
        return new MongoPreparedStatement(this, this.connection, 1003, 1007, sql);
    }

    public PreparedStatement prepareStatement(String sql, String[] columnNames)
            throws SQLException
    {
        return new MongoPreparedStatement(this, this.connection, 1003, 1007, sql);
    }

    public Array createArrayOf(String typeName, Object[] elements)
            throws SQLException
    {
        MongoArray mArray = null;

        if (Attribute.getType(typeName) == 2003)
        {
            mArray = new MongoArray(elements);
        }
        else if (Attribute.getType(typeName) == -2000)
        {
            mArray = new MongoArray(elements);
        }
        else if (Attribute.getType(typeName) == 12)
        {
            mArray = new MongoArray(elements);
        }
        else
        {
            mArray = new MongoArray(elements);
        }

        return mArray;
    }

    public void rebuildSchema()
            throws SQLException
    {
        ((ServerConnection)this.connection).buildSchema();
    }

    public DB getDB()
    {
        if (this.connection == null)
            return null;
        return ((ServerConnection)this.connection).getDB();
    }

    public GlobalSchema getGlobalSchema()
    {
        if (this.connection == null) {
            return null;
        }
        return ((ServerConnection)this.connection).getSchema();
    }
}